Шаг 6. Сжимаем коммиты c помощью опции squash
Бывает так: вы создали отдельную ветку и долго в ней работаете. Сделали в этой ветке много коммитов, и, возможно, не все из них хорошие.
Или так: вы отправили запрос на слияние, но руководитель проекта нашёл ошибки. Вы их исправили и каждую ошибку закоммитили отдельно, чтобы проверяющий мог быстрее разобраться в ваших исправлениях.
Эти мелкие коммиты актуальны только на момент работы или проверки, а после их нужно объединить в один. Если вы выполните обычное слияние, через fast-forward или no-fast-forward, коммиты всё равно перенесутся во вливаемую ветку, а нам бы этого не хотелось. На этот случай есть решение — опция --squash. Она позволяет сжать коммиты и создать из них один.
Давайте посмотрим, как работает squash.
Для начала убедитесь, что вы находитесь в ветке develop. Если нет, переключитесь на неё — git switch develop.
Чтобы понять смысл сквоша, сделаем два изменения и закоммитим каждое по отдельности. Для этого перейдём в index.html. Сначала сделаем первое изменение — исправим отступы для элемента <head> и <body>.
Добавляем изменение в индекс — git add -A.
После этого сделаем фиксацию изменения — git commit --message "feat: added indents for nested html tag elements in index.html".
Внесём второе изменение. Поменяем местами атрибуты у элемента <link>.
Снова добавим изменение в индекс — git add --all, а затем выполним фиксацию — git commit --message "feat: the attributes of the link element have been swapped".
После этого переключаемся на ветку main с помощью команды git switch main.
Как вы можете заметить, изменения тоже исчезли. Теперь можно приступать к сжатию коммитов с помощью опции --squash. Для этого пропишем команду git merge develop --squash.
Изменения перенеслись.
У вас мог появиться вопрос, что произошло и в чём разница? При использовании опции --squash переносятся лишь сделанные изменения, и они сразу добавляются в индекс, чтобы мы смогли самостоятельно создать коммит.
Что ещё важно знать:
- Слияние всегда будет происходить с использованием режима fast-forward. Если дополнительно к опции
--squashнаписать--no-ffдля использования режима no-fast-forward, она будет проигнорирована. Точно так же будет проигнорирована опция--messageили-mдля написания текста коммита слияния, потому что коммит мы будем создавать сами. - Коммиты не переносятся — переносятся только сделанные изменения. Поэтому может возникнуть проблема с удалением ветки через опцию
--delete, в нашем случае веткиdevelop. Дело в том, что коммиты не были перенесены, и Git до сих пор думает, что слияние не произошло. Чтобы удалить ветку, понадобится опция--force, которая сделает это принудительно. - Так как коммиты не перенесены, указатель HEAD не будет обновлён. Он продолжит указывать на последний сделанный коммит в ветке
main. Лишь когда мы сделаем коммит из перенесённых изменений — только тогда указатель переместится, ведь этот коммит будет считаться последним.
Это всё, что важно знать про опцию. Теперь закоммитим изменения с помощью команды git commit --message "feat: tabulation has been added, and the attributes of the link element have been swapped".
На самом деле это пример не лучшего коммита, так он объединяет несколько разных изменений. Мы сделали так, чтобы показать работу squash. Но при работе над реальными проектами помните: коммиты не должны описывать разные изменения.
Теперь отправим изменение в удалённый репозиторий с помощью команды git push.
Далее удалим ветку develop: она нам пока что не понадобится, в следующих демонстрациях мы создадим другую. Для удаления воспользуемся командой git branch -D develop.
Мы удалили ветку лишь локально — теперь её нужно убрать из удалённого репозитория. Для этого воспользуемся командой git push --delete origin develop.
Если вам понадобятся коммиты из ветки develop, можно будет сделать обычное слияние.
В одной из будущих демонстраций мы разберём более удобный способ сжатия коммитов. Сейчас мы перемещали изменения на другую ветку, а в другом примере мы будем работать на той же ветке. Потом этот коммит можно будет влить в другую ветку.